﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Com.Binaria.Core;
using Com.Binaria.Core.Enumeracion;
using Com.Binaria.Core.Exceptions;
using Com.Binaria.SISCOB.DTO;
using Com.Binaria.SISCOB.Dom;
using Com.Binaria.SISCOB.Funcional.DTO;
using Com.Binaria.Core.Util;

namespace Com.Binaria.SISCOB.Mgr
{

    public class EgresoMgr : IEgresoMgr
    {
        #region ATRIBUTOS A EXPONER AL USUARIO
        public IEgresoDom iEgresoDom;
        public IDocumentoTransaccionDom iDocumentoTransaccionDom;
        public IDocumentoTransaccionMgr iDocumentoTransaccionMgr;
        public IConstante iConstante;
        public IItemConceptoDom iItemConceptoDom;
        #endregion

        #region Miembros de IEgresoMgr
        public EgresoFuncionalDTO GetById(ContextoDTO oContexto, System.Int32? Id)
        {
            EgresoFuncionalDTO oItem = null;
            //
            try
            {
                EgresoDTO tmp = iEgresoDom.BuscarEgresoPorId(oContexto, Id);
                if (tmp != null)
                {
                    oItem = new EgresoFuncionalDTO();
                    oItem.Id = tmp.Id;
                    oItem.EsManual = Convert.ToBoolean(tmp.EsManual);
                    oItem.Estado = tmp.Estado;
                    oItem.EstadoText = iConstante.getDomains("domEstadoEgreso").Where(itm => itm.Clave.Equals(oItem.Estado)).First().Valor;
                    //Relacion : DocumentoTransaccion
                    DocumentoTransaccionDTO oRel1 = new DocumentoTransaccionDTO();
                    oRel1.IdEgreso = Id;

                    IList<DocumentoTransaccionDTO> oRel1s = iDocumentoTransaccionDom.BuscarDocumentoTransaccionFiltro(oContexto, oRel1);
                    if (oRel1s != null && oRel1s.Count > 0)
                    {
                        //oItem.DocumentoTransaccion = new DocumentoTransaccionFuncionalDTO();
                        //oItem.DocumentoTransaccion.Id = oRel1s[0].Id;
                        //oItem.DocumentoTransaccion.Sucursal = Convert.ToInt32(oRel1s[0].IdSucursal);
                        //oItem.DocumentoTransaccion.CuentaCorriente = Convert.ToInt32(oRel1s[0].IdCuentaCorriente);
                        //oItem.DocumentoTransaccion.Monto = Convert.ToInt64(oRel1s[0].Monto);
                        //oItem.DocumentoTransaccion.FchDocumento = oRel1s[0].FchDocumento;
                        //oItem.DocumentoTransaccion.FchUpdate = oRel1s[0].FchUpdate;
                        //oItem.DocumentoTransaccion.Glosa = oRel1s[0].Glosa;
                        //oItem.DocumentoTransaccion.NmrDocumento = oRel1s[0].NmrDocumento;
                        //oItem.DocumentoTransaccion.EstaActivo = Convert.ToBoolean(oRel1s[0].EstaActivo);

                        oItem.DocumentoTransaccion = iDocumentoTransaccionMgr.GetById(oContexto, oRel1s[0].Id);
                    }
                }
            }
            catch (Exception ex) { throw new ManagerException(ex.Message, System.Diagnostics.TraceEventType.Warning); }
            return oItem;
        }

        public IList<EgresoFuncionalDTO> GetAll(ContextoDTO oContexto)
        {
            IList<EgresoFuncionalDTO> oItem = null;
            //
            try
            {
                IList<EgresoDTO> tmp = iEgresoDom.BuscarEgresoTodos(oContexto);
                if (tmp != null)
                {
                    oItem = new List<EgresoFuncionalDTO>(tmp.Count);
                    for (int i = 0; i < tmp.Count; i++)
                    {
                        EgresoFuncionalDTO oFDto = new EgresoFuncionalDTO();
                        //oFDto.Id = tmp[i].Id;
                        //oFDto.EsManual = Convert.ToBoolean(tmp[i].EsManual);
                        //oFDto.Estado = tmp[i].Estado;

                        oFDto = GetById(oContexto, tmp[i].Id);
                        //
                        oItem.Add(oFDto);
                    }
                }
            }
            catch (Exception ex) { throw new ManagerException(ex.Message, System.Diagnostics.TraceEventType.Warning); }
            return oItem;
        }

        public IList<EgresoFuncionalDTO> GetBy(ContextoDTO oContexto, EgresoFuncionalDTO item)
        {
            IList<EgresoFuncionalDTO> oItem = null;
            //
            try
            {
                IList<EgresoDTO> tmp = null;
                if (item == null)
                    tmp = iEgresoDom.BuscarEgresoTodos(oContexto);
                else
                {
                    EgresoDTO oDto = new EgresoDTO();
                    oDto.Id = item.Id;
                    if (!string.IsNullOrEmpty(item.Estado)) oDto.Estado = item.Estado;
                    //
                    if (item.IsCaducados)
                        tmp = iEgresoDom.BuscarEgresoCaducados(oContexto, item.FchConsulta, item.DiasMaximos);
                    else
                        tmp = iEgresoDom.BuscarEgresoFiltro(oContexto, oDto);
                }

                if (tmp != null)
                {
                    oItem = new List<EgresoFuncionalDTO>(tmp.Count);
                    for (int i = 0; i < tmp.Count; i++)
                    {
                        EgresoFuncionalDTO oFDto = new EgresoFuncionalDTO();
                        //oFDto.Id = tmp[i].Id;
                        //oFDto.EsManual = Convert.ToBoolean(tmp[i].EsManual);
                        //oFDto.Estado = tmp[i].Estado;
                        //
                        oFDto = GetById(oContexto, tmp[i].Id);

                        oItem.Add(oFDto);
                    }
                }
            }
            catch (Exception ex) { throw new ManagerException(ex.Message, System.Diagnostics.TraceEventType.Warning); }
            return oItem;
        }

        [Binaria.Core.Attribute.Trasanction(System.Transactions.TransactionScopeOption.Required)]
        public bool Save(ContextoDTO oContexto, EgresoFuncionalDTO item)
        {
            bool IsOK = false;
            bool IsExist = (item.Id.HasValue && item.Id > 0);
            List<int> oUpd = null;
            List<DocumentoTransaccionDTO> listDocTranDTO = null;
            DocumentoTransaccionDTO oRel1 = null;

            try
            {

                EgresoDTO oDto = new EgresoDTO();
                oDto.Id = item.Id;
                oDto.EsManual = item.EsManual;
                oDto.Estado = item.Estado;

                if (IsExist)
                    iEgresoDom.RegistrarEgreso(oContexto, new List<EgresoDTO>() { oDto }, EnumRegistrarAccion.Modificar);
                else
                {
                    iEgresoDom.RegistrarEgreso(oContexto, new List<EgresoDTO>() { oDto }, EnumRegistrarAccion.Agregar);
                }

                //Relacion MD11: DocumentoTransaccion
                if (item.DocumentoTransaccion != null)
                {
                    oRel1 = new DocumentoTransaccionDTO();
                    oRel1.Id = item.DocumentoTransaccion.Id;
                    oRel1.IdEgreso = oDto.Id;
                    oRel1.Egreso = oDto;
                    if (item.DocumentoTransaccion.Sucursal > 0) oRel1.IdSucursal = item.DocumentoTransaccion.Sucursal;
                    oRel1.IdCuentaCorriente = item.DocumentoTransaccion.CuentaCorriente;
                    oRel1.Monto = item.DocumentoTransaccion.Monto;
                    oRel1.FchDocumento = item.DocumentoTransaccion.FchDocumento;
                    oRel1.FchUpdate = item.DocumentoTransaccion.FchUpdate;
                    oRel1.Glosa = item.DocumentoTransaccion.Glosa;
                    oRel1.NmrDocumento = item.DocumentoTransaccion.NmrDocumento;
                    oRel1.UserName = item.DocumentoTransaccion.UserName;
                    oRel1.EstaActivo = true;

                    if (oRel1.Id.HasValue && oRel1.Id > 0)
                        iDocumentoTransaccionDom.RegistrarDocumentoTransaccion(oContexto, new List<DocumentoTransaccionDTO>() { oRel1 }, EnumRegistrarAccion.Modificar);
                    else
                        iDocumentoTransaccionDom.RegistrarDocumentoTransaccion(oContexto, new List<DocumentoTransaccionDTO>() { oRel1 }, EnumRegistrarAccion.Agregar);
                }

                // Actualizar documentos relacionados con documento actualizado
                listDocTranDTO = iDocumentoTransaccionDom.BuscarByEgreso(oContexto, oRel1);
                if (listDocTranDTO.Count > 1)
                {
                    foreach (DocumentoTransaccionDTO dtDTO in listDocTranDTO)
                    {
                        dtDTO.Egreso = iEgresoDom.BuscarEgresoPorId(oContexto, dtDTO.IdEgreso);
                        if (dtDTO.Egreso.Estado.Equals(oRel1.Egreso.Estado))
                        {
                            if (dtDTO.Id.Value != oRel1.Id.Value)
                            {

                                if (dtDTO.Monto.Value != oRel1.Monto.Value)
                                {
                                    DocumentoTransaccionDTO newDTO = dtDTO.Clone();
                                    newDTO.Monto += oRel1.Monto;
                                    iDocumentoTransaccionDom.RegistrarDocumentoTransaccion(oContexto, new List<DocumentoTransaccionDTO>() { newDTO }, EnumRegistrarAccion.Modificar);
                                }
                            }
                            else
                            {
                                this.Delete(oContexto, new EgresoFuncionalDTO() { Id = dtDTO.IdEgreso, DocumentoTransaccion = new DocumentoTransaccionFuncionalDTO() { Id = dtDTO.Id } });
                            }
                        }
                    }

                    foreach (DocumentoTransaccionDTO dtDTO in listDocTranDTO)
                    {
                        dtDTO.Egreso = iEgresoDom.BuscarEgresoPorId(oContexto, dtDTO.IdEgreso);

                        if (dtDTO.Egreso != null)
                        {
                            if ((oRel1.Egreso.Estado.Equals("ON")) && dtDTO.Egreso.Estado.Equals("GI") || (oRel1.Egreso.Estado.Equals("GI")) && dtDTO.Egreso.Estado.Equals("ON"))
                            {
                                Factoria.Log.Info("11");
                                this.iDocumentoTransaccionDom.Conciliar(oContexto, new List<DocumentoTransaccionDTO>() { dtDTO });
                            }
                        }
                    }

                }

                if (listDocTranDTO.Count == 1 && IsExist)
                {
                    throw new ManagerException(Factoria.GetMessage("MGR_EGRESO_ERRORCHANGE"), System.Diagnostics.TraceEventType.Warning);
                }

                IsOK = true;
            }
            catch (Exception ex) { throw new ManagerException(ex.Message, System.Diagnostics.TraceEventType.Warning); }
            return IsOK;
        }

        [Binaria.Core.Attribute.Trasanction(System.Transactions.TransactionScopeOption.Required)]
        public bool Delete(ContextoDTO oContexto, EgresoFuncionalDTO item)
        {
            bool IsOK = false;
            bool IsExist = (item.Id.HasValue && item.Id > 0);

            try
            {
                EgresoDTO oDto = new EgresoDTO();
                oDto.Id = item.Id;

                if (IsExist)
                {
                    //Relacion :  DocumentoTransaccion
                    DocumentoTransaccionDTO oRel1 = new DocumentoTransaccionDTO();
                    oRel1.Id = item.DocumentoTransaccion.Id;
                    List<DocumentoTransaccionDTO> oRel1s = iDocumentoTransaccionDom.BuscarDocumentoTransaccionFiltro(oContexto, oRel1);
                    List<ItemConceptoDTO> listItemConceptoDTO = iItemConceptoDom.BuscarItemConceptoFiltro(oContexto, new ItemConceptoDTO() { IdDocumentoTransaccion = oRel1.Id });
                    if (listItemConceptoDTO != null && listItemConceptoDTO.Count > 0)
                    {
                        iItemConceptoDom.RegistrarItemConcepto(oContexto, listItemConceptoDTO, EnumRegistrarAccion.Eliminar);
                    }
                    if (oRel1s != null && oRel1s.Count > 0)
                    {
                        iDocumentoTransaccionDom.RegistrarDocumentoTransaccion(oContexto, oRel1s, EnumRegistrarAccion.Eliminar);
                    }
                    iEgresoDom.RegistrarEgreso(oContexto, new List<EgresoDTO>() { oDto }, EnumRegistrarAccion.Eliminar);
                }
                IsOK = true;
            }
            catch (Exception ex) { throw new ManagerException(ex.Message, System.Diagnostics.TraceEventType.Warning); }
            return IsOK;
        }

        public IList<EgresoFuncionalDTO> GetAllPag(ContextoDTO oContexto, EgresoFuncionalDTO item)
        {
            IList<EgresoFuncionalDTO> oItem = null;
            //
            try
            {
                IList<EgresoDTO> tmp = null;
                if (item == null)
                    tmp = iEgresoDom.BuscarEgresoTodos(oContexto);
                else
                {
                    EgresoDTO oDto = new EgresoDTO();
                    oDto.DocumentoTransaccion = new DocumentoTransaccionDTO();
                    oDto.Id = item.Id;
                    if (!string.IsNullOrEmpty(item.Estado)) oDto.Estado = item.Estado;
                    if (item.DocumentoTransaccion != null) oDto.DocumentoTransaccion.NmrDocumento = item.NmrDocumento;
                    if (item.DocumentoTransaccion != null) oDto.DocumentoTransaccion.FchDocumento = (DateTime?)item.DocumentoTransaccion.FchDocumento;
                    if (item.DocumentoTransaccion != null && item.DocumentoTransaccion.Monto > 0) oDto.DocumentoTransaccion.Monto = (long?)item.DocumentoTransaccion.Monto;
                    if (item.DocumentoTransaccion != null && item.DocumentoTransaccion.CuentaCorriente > 0) oDto.DocumentoTransaccion.IdCuentaCorriente = (int?)item.DocumentoTransaccion.CuentaCorriente;

                    if (item.Pagina > 0) oDto.Pagina = item.Pagina;
                    if (item.SizePagina > 0) oDto.SizePagina = item.SizePagina;
                    if (!string.IsNullOrEmpty(item.ColumnOrden)) oDto.ColumnOrden = item.ColumnOrden;
                    if (!string.IsNullOrEmpty(item.TipoOrden)) oDto.TipoOrden = item.TipoOrden;
                    //Propiedades Extendidas
                    if (!string.IsNullOrEmpty(item.FchDesde))
                    {
                        string[] sVal = item.FchDesde.Split(new char[] { '/', '-' }, StringSplitOptions.RemoveEmptyEntries);
                        if (sVal.Length == 3)
                            oDto.FchDesde = new Nullable<DateTime>(new DateTime(Convert.ToInt32(sVal[2]), Convert.ToInt32(sVal[1]), Convert.ToInt32(sVal[0])));
                    }
                    if (!string.IsNullOrEmpty(item.FchHasta))
                    {
                        string[] sVal = item.FchHasta.Split(new char[] { '/', '-' }, StringSplitOptions.RemoveEmptyEntries);
                        if (sVal.Length == 3)
                            oDto.FchHasta = new Nullable<DateTime>(new DateTime(Convert.ToInt32(sVal[2]), Convert.ToInt32(sVal[1]), Convert.ToInt32(sVal[0])));
                    }
                    //
                    tmp = iEgresoDom.BuscarEgresoFiltroPaginado(oContexto, oDto);
                }

                if (tmp != null)
                {
                    oItem = new List<EgresoFuncionalDTO>(tmp.Count);
                    for (int i = 0; i < tmp.Count; i++)
                    {
                        EgresoFuncionalDTO oFDto = new EgresoFuncionalDTO();
                        //oFDto.Id = tmp[i].Id;
                        //oFDto.EsManual = Convert.ToBoolean(tmp[i].EsManual);
                        //oFDto.Estado = tmp[i].Estado;
                        //
                        oFDto = GetById(oContexto, tmp[i].Id);
                        oFDto.TotalRegistros = Convert.ToInt64(tmp[i].TotalRegistros);

                        oItem.Add(oFDto);
                    }
                }
            }
            catch (Exception ex) { throw new ManagerException(ex.Message, System.Diagnostics.TraceEventType.Warning); }
            return oItem;
        }


        #endregion
    }
}
